package ui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;

import model.Country;
import util.ImagePanel;
import util.PdfFilePrint;
import controller.CountryController;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;

public class CountryUI implements ActionListener
{

	private static CountryUI instance = null;

	private boolean startup = false;

	private CountryController countryCtrl;

	private JFrame frameCountryUI;

	private JTabbedPane tabbedPane;

	private ImagePanel newCountries;
	private ImagePanel allCountries;

	private Image image = null;

	private JLabel countries;
	private JLabel newCountry;
	private JLabel newCountryTldLabel;
	private JLabel searchBy;

	private JTable allCountriesTable;

	private DefaultTableModel allCountriesTableModel;

	private JScrollPane allCountriesTableScroll;

	private JButton createCountry;
	private JButton emptySearchList;
	private JButton editCountry;
	private JButton statistics;
	private JButton btnBack;

	private JTextField newCountryName;
	private JTextField newCountryTld;
	private JTextField searchWith;

	private JComboBox<String> comboBoxSearch;

	private ArrayList<Country> countryList;

	private backButton back;
	private JButton printBtn;

	public void display()
	{
		frameCountryUI.setSize(700, 400);
		frameCountryUI.setVisible(true);
		frameCountryUI.setResizable(false);
		frameCountryUI.setLocationRelativeTo(null);
	}

	public CountryUI()
	{
		frameCountryUI = new MainWindow();

		back = new backButton();

		countries = new JLabel("COUNTRIES");
		countries.setBounds(9, 1 , 123, 28);
		countries.setForeground(Color.white);
		countries.setFont(new Font("Dialog", Font.BOLD, 20));

		frameCountryUI.getContentPane().add(countries);

		createCountry = new JButton();
		createCountry.setBounds(286, 110, 103, 23);
		createCountry.setText("Create Country");
		createCountry.setOpaque(false);
		createCountry.addActionListener(this);

		emptySearchList = new JButton();
		emptySearchList.setBounds(286, 110, 103, 23);
		emptySearchList.setText("Clear Search");
		emptySearchList.setOpaque(false);
		emptySearchList.addActionListener(this);

		comboBoxSearch = new JComboBox<String>();
		comboBoxSearch.addActionListener(this);
		comboBoxSearch.addItem("Everything");
		comboBoxSearch.addItem("Name");
		comboBoxSearch.addItem("Tld");


		editCountry = new JButton();
		editCountry.setBounds(286, 110, 103, 23);
		editCountry.setText("Edit Country");
		editCountry.setOpaque(false);
		editCountry.addActionListener(this);

		statistics = new JButton();
		statistics.setLocation(584, 326);
		statistics.setSize(100, 20);
		statistics.setOpaque(false);
		statistics.setText("Statistics");
		statistics.addActionListener(this);

		frameCountryUI.getContentPane().add(statistics);

		try
		{
			image = ImageIO.read(new File("img/background/background.jpg"));
		}
		catch(Exception e)
		{
			msgError(null, "Could not load background");
		}

		tabbedPane = new JTabbedPane();
		tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		tabbedPane.setBounds(0, 31, 694, 289);

		frameCountryUI.getContentPane().add(tabbedPane);

		//new Country panel

		newCountries = new ImagePanel(image);
		newCountries.setBounds(0, 31, 694, 289);

		newCountry = new JLabel("Country name:");
		newCountryTldLabel = new JLabel("Country Tld:");

		newCountryName = new JTextField();
		newCountryTld = new JTextField();


		allCountries = new ImagePanel(image);
		allCountries.setBounds(0, 31, 694, 289);

		searchBy = new JLabel("Search For:");
		searchWith = new JTextField();
		searchWith.getDocument().addDocumentListener(new DocumentListener()
		{
			@Override
			public void changedUpdate(DocumentEvent arg0)
			{
				searchCountries();
			}

			@Override
			public void insertUpdate(DocumentEvent arg0)
			{
				searchCountries();

			}

			@Override
			public void removeUpdate(DocumentEvent arg0)
			{
				searchCountries();

			}
		});

		// all countries panel

		countryCtrl = new CountryController();

		String allCountriesColumns[] = { "#", "Name", "Tld", ""};

		allCountriesTableModel = new DefaultTableModel(null, allCountriesColumns);

		allCountriesTable = new JTable(allCountriesTableModel)
		{
			private static final long serialVersionUID = 1L;

			public boolean isCellEditable(int rowIndex, int colIndex)
			{
				return false;
			}
			public Class<?> getColumnClass(int column)
			{
				return getValueAt(0, column).getClass();
			}
		};
		Dimension d = allCountriesTable.getPreferredSize();
		double width = d.width / allCountriesColumns.length;
		double [] width_2 = {0.3, 1.0, 0.3, 0.3};

		for (int i = 0; i < allCountriesColumns.length; i++)
			allCountriesTable.getColumnModel().getColumn(i).setPreferredWidth((int) (width*width_2[i]));

		allCountriesTable.setAutoCreateRowSorter(true);

		allCountriesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		allCountriesTableScroll = new JScrollPane(allCountriesTable);



		tabbedPane.addTab("All Countries", allCountries);

		JLabel lblSearchBy = new JLabel("Search by:");
		GroupLayout gl_allCountries = new GroupLayout(allCountries);
		gl_allCountries.setHorizontalGroup(
				gl_allCountries.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, gl_allCountries.createSequentialGroup()
						.addContainerGap()
						.addGroup(gl_allCountries.createParallelGroup(Alignment.TRAILING)
								.addComponent(allCountriesTableScroll, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 669, Short.MAX_VALUE)
								.addGroup(Alignment.LEADING, gl_allCountries.createSequentialGroup()
										.addGroup(gl_allCountries.createParallelGroup(Alignment.TRAILING, false)
												.addGroup(Alignment.LEADING, gl_allCountries.createSequentialGroup()
														.addComponent(lblSearchBy, GroupLayout.PREFERRED_SIZE, 56, GroupLayout.PREFERRED_SIZE)
														.addPreferredGap(ComponentPlacement.RELATED)
														.addComponent(comboBoxSearch, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
														.addGroup(Alignment.LEADING, gl_allCountries.createSequentialGroup()
																.addComponent(searchBy)
																.addPreferredGap(ComponentPlacement.RELATED)
																.addComponent(searchWith, GroupLayout.PREFERRED_SIZE, 145, GroupLayout.PREFERRED_SIZE)))
																.addPreferredGap(ComponentPlacement.RELATED)
																.addComponent(emptySearchList)
																.addPreferredGap(ComponentPlacement.RELATED, 272, Short.MAX_VALUE)
																.addComponent(editCountry)))
																.addContainerGap())
				);
		gl_allCountries.setVerticalGroup(
				gl_allCountries.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_allCountries.createSequentialGroup()
						.addContainerGap()
						.addGroup(gl_allCountries.createParallelGroup(Alignment.BASELINE)
								.addComponent(comboBoxSearch, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addComponent(lblSearchBy))
								.addPreferredGap(ComponentPlacement.RELATED)
								.addGroup(gl_allCountries.createParallelGroup(Alignment.BASELINE)
										.addComponent(searchBy)
										.addComponent(searchWith, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
										.addComponent(editCountry)
										.addComponent(emptySearchList))
										.addPreferredGap(ComponentPlacement.RELATED)
										.addComponent(allCountriesTableScroll, GroupLayout.DEFAULT_SIZE, 181, Short.MAX_VALUE)
										.addContainerGap())
				);
		allCountries.setLayout(gl_allCountries);


		tabbedPane.addTab("New Country", newCountries);
		GroupLayout gl_newCountries = new GroupLayout(newCountries);
		gl_newCountries.setHorizontalGroup(
				gl_newCountries.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_newCountries.createSequentialGroup()
						.addContainerGap(250, Short.MAX_VALUE)
						.addGroup(gl_newCountries.createParallelGroup(Alignment.LEADING)
								.addGroup(Alignment.TRAILING, gl_newCountries.createSequentialGroup()
										.addGroup(gl_newCountries.createParallelGroup(Alignment.LEADING)
												.addComponent(newCountry)
												.addComponent(newCountryTldLabel))
												.addGap(18)
												.addGroup(gl_newCountries.createParallelGroup(Alignment.LEADING, false)
														.addComponent(newCountryTld, Alignment.TRAILING)
														.addComponent(newCountryName, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 111, GroupLayout.PREFERRED_SIZE))
														.addGap(238))
														.addGroup(Alignment.TRAILING, gl_newCountries.createSequentialGroup()
																.addComponent(createCountry)
																.addGap(286))))
				);
		gl_newCountries.setVerticalGroup(
				gl_newCountries.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_newCountries.createSequentialGroup()
						.addGap(73)
						.addGroup(gl_newCountries.createParallelGroup(Alignment.BASELINE)
								.addComponent(newCountryName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addComponent(newCountry))
								.addPreferredGap(ComponentPlacement.UNRELATED)
								.addGroup(gl_newCountries.createParallelGroup(Alignment.BASELINE)
										.addComponent(newCountryTld, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
										.addComponent(newCountryTldLabel))
										.addGap(18)
										.addComponent(createCountry)
										.addContainerGap(96, Short.MAX_VALUE))
				);
		newCountries.setLayout(gl_newCountries);

		btnBack = new JButton();
		btnBack.setText("Back");
		btnBack.setOpaque(false);
		btnBack.setBounds(10, 326, 100, 20);
		btnBack.addActionListener(this);
		frameCountryUI.getContentPane().add(btnBack);

		printBtn = new JButton();
		printBtn.addActionListener(this);
		printBtn.setText("Print");
		printBtn.setOpaque(false);
		printBtn.setBounds(474, 326, 100, 20);
		frameCountryUI.getContentPane().add(printBtn);


		try
		{
			updateCountryList();
		}
		catch(Exception e)
		{
			msgError(null, "Could not load information");
		}

	}

	private void updateCountryList()
	{
		try
		{ 
			countryList = countryCtrl.findCountriesByAllInfo("");
			allCountriesUpdateTable(countryList);
		}
		catch(Exception e)
		{
			msgError(newCountries,"Could not load countries");
		}
	}

	@Override
	public void actionPerformed(ActionEvent e)
	{
		frameCountryUI.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		if(e.getSource() == createCountry)
		{
			addCountry();
		}
		else if(e.getSource() == emptySearchList)
		{
			comboBoxSearch.setSelectedIndex(0);
			searchWith.setText(null);
		}
		else if(e.getSource() == editCountry)
		{
			showEditCountryDialog();
		}
		else if(e.getSource() == statistics)
		{
			StatisticsUI stats = StatisticsUI.getInstance();
			stats.display();
			frameCountryUI.setVisible(false);
		}
		else if (e.getSource() == comboBoxSearch)
		{
			if(startup)
				searchCountries();
		}
		else if (e.getSource() == btnBack)
		{
			back.eraseLast();
			back.goBack(back.getNumber());
		}
		else if (e.getSource() == printBtn)
		{
			printCountryPDF();
		}

		frameCountryUI.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
	}

	private void printCountryPDF()
	{
		if (allCountriesTable.getRowCount() > 0)
		{
			ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();

			String columns [] = {  "#", "Name" };

			ArrayList<String> countryID = new ArrayList<String>();
			ArrayList<String> countryName = new ArrayList<String>();

			list.add(countryID);
			list.add(countryName);

			for(int i = 0; i < allCountriesTable.getRowCount(); i++)
			{
				list.get(0).add(String.valueOf(allCountriesTable.getValueAt(i, 0)));
				list.get(1).add(String.valueOf(allCountriesTable.getValueAt(i, 1)));
			}

			PdfFilePrint pdfPrint = new PdfFilePrint();
			boolean successPDF = pdfPrint.PDFPrint("Countries", "Current Countries", "country", "Nikola", columns, list);

			if(successPDF)
				msgSuccess(null, "PDF was created successfully");
			else
				msgError(null, "There was an error creating the PDF");
		}
		else
		{
			msgError(null, "Nothing to print");
		}
	}

	private boolean checkInfo(JTextField textField)
	{
		if((textField.getText().trim().length() == 0) || (textField.getText().trim().length() > 32))
			return false;

		return true;
	}
	private boolean checkTldInfo(JTextField textField)
	{
		if((textField.getText().trim().length() == 0) || (textField.getText().trim().length() > 2))
			return false;

		return true;
	}

	private void addCountry()
	{
		boolean validInfo = checkInfo(newCountryName);
		boolean tldValidInfo = checkTldInfo(newCountryTld);

		if(validInfo && tldValidInfo)
		{
			try
			{
				int good = countryCtrl.createCountry(newCountryName.getText().trim(), newCountryTld.getText().trim());

				if(good > 0)
				{
					msgSuccess(newCountries, "Country \"" + newCountryName.getText() + "\" with Tld \"" + newCountryTld.getText() + "\" has been added successfully");

					newCountryName.setText(null);
					newCountryTld.setText(null);

					searchCountries();
				} // end of if
				else if (good < 0)
				{
					msgError(newCountries, "There was an error adding the country.\n");
				} // end of else
			} // end of try
			catch(Exception ex)
			{
				msgError(newCountries, "There was an error adding the country.");
			} // end of catch
		} // end of if
		else if(!validInfo)
		{
			msgError(newCountries, "You cannot proceed due to errors in your input.\nThe text area can not have more then 32 symbols or less then 1.");
		}
		else if(!tldValidInfo)
		{
			msgError(newCountries, "You cannot proceed due to errors in your input.\nThe text area can not have more then 2 symbols or less then 1.");
		}

	}
	private void showEditCountryDialog()
	{
		if(allCountriesTable.getSelectedRow() > -1)
		{
			int countryID = Integer.valueOf(String.valueOf(allCountriesTable.getValueAt(allCountriesTable.getSelectedRow(), 0)));

			Country country = new Country();
			try
			{
				country = countryCtrl.getOneCountry("id", String.valueOf(countryID));
			} catch (SQLException e)
			{
				msgError(newCountries, "Could not load needed country information");
				e.printStackTrace();
			}

			JPanel panel = new JPanel(new GridLayout(0,2,5,5));

			JTextField editCountryName = new JTextField(country.getName());
			JTextField editCountryTld = new JTextField(country.getTld());

			panel.add(new JLabel("Country name:"));
			panel.add(editCountryName);
			panel.add(new JLabel("Country tld:"));
			panel.add(editCountryTld);

			int option = JOptionPane.showConfirmDialog(allCountries, panel, "Edit country", JOptionPane.OK_CANCEL_OPTION);

			if(option == JOptionPane.YES_OPTION)
			{
				boolean validInfo = checkInfo(editCountryName);
				boolean tldValidInfo = checkTldInfo(editCountryTld);
				if(validInfo && tldValidInfo)
				{
					System.out.println("ID IS []!!! : " + country.getCountryID() + country.getName() + country.getTld());
					int success = 0;
					try
					{
						success = countryCtrl.updateCountry( countryID,editCountryName.getText().trim(), editCountryTld.getText().trim());
					} catch (SQLException e)
					{
						msgError(newCountries, "Could not edit country information");
						e.printStackTrace();
					}

					if(success > 0)
					{
						msgSuccess(newCountries, "Country has been edited successfully");
						searchCountries();
					} // end of if
					else
					{
						msgError(newCountries, "There was an error while editing the country");
					} // end of else
				} // end of if
				else if(!validInfo)
				{
					msgError(newCountries, "You have over 32 symbols or the name field is empty");
				} // end of else
				else if(!tldValidInfo)
				{
					msgError(newCountries, "You have over 2 symbols or the tld field is empty");
				}
			} // end of if

		} // end of if
		else
		{
			msgError(allCountries, "You have not selected a country");
		} // end of else
	}

	public void allCountriesUpdateTable(ArrayList<Country> countryLister)

	{
		if(countryLister.size() > 0)
		{
			tableClearList();

			for(Country country : countryLister)
			{
				allCountriesTableModel.addRow(
						new Object[] 
								{
								country.getCountryID(),
								country.getName(),
								country.getTld(),
								new ImageIcon("img/flags/" + country.getTld() + ".png")
								}
						);
			} // end for
		} // end if
	}
	public void tableClearList()
	{
		DefaultTableModel dTM = (DefaultTableModel) allCountriesTable.getModel();

		while(dTM.getRowCount() > 0)
			dTM.removeRow(0);

	}
	public void searchCountries()
	{
		ArrayList<Country> countryLister = new ArrayList<Country>();

		String clause = comboBoxSearch.getSelectedItem().toString().toLowerCase();
		String search = searchWith.getText();

		try
		{
			tableClearList();
			switch(clause)
			{
				case "everything" : countryLister = countryCtrl.findCountriesByAllInfo(search); break;
				case "name" : countryLister = countryCtrl.findByName(search); break;
				case "tld" : countryLister = countryCtrl.findByTld(search); break;
			} // end of switch
			//	if(cityListTwo.size() > 0)
			allCountriesUpdateTable(countryLister);
			for(int i= 0; i < countryLister.size(); i++)
			{
				System.out.println("[CITY IN LIST]");		
				System.out.println(countryLister.get(i));
			}
		} // end of try
		catch (Exception e)
		{
			msgError(allCountries, "Could not load cities");
			e.printStackTrace();
		}

		if (!startup)
			startup = true;
	}
	private void msgError(JPanel panel, String error)
	{
		JOptionPane.showConfirmDialog(panel, error, "Error", JOptionPane.PLAIN_MESSAGE, JOptionPane.ERROR_MESSAGE);
	}

	private void msgSuccess(JPanel panel, String success)
	{
		JOptionPane.showMessageDialog(panel, success, "Success", 1);
	}
	public static CountryUI getInstance()
	{
		if(instance == null)
			instance = new CountryUI();

		return instance;

	}
	public static void main(String[] args)
	{
		try 
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 

			CountryUI countryUI = new CountryUI();
			countryUI.display();
		}
		catch(Exception e)
		{
			System.out.println("[ERROR] City Menu cannot load");
			e.printStackTrace();
		}
	}
}
